package com.njbw.rateLimit;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * 漏桶算法
 *
 * @author 黄侯淳
 * @since JDK 1.8
 */
public class Funnel {

    // 出口流量速率 1s 10个
    private int rate = 10;

    // 漏桶
    private ArrayBlockingQueue bucket;

    public Funnel(int rate, int capacity) {
        this.rate = rate;
        this.bucket = new ArrayBlockingQueue<>(capacity);
        int speed = 1000 / this.rate;
        // 固定速率滴水
        new Thread(() -> {
            while (true) {
                bucket.poll();
                try {
                    Thread.sleep(speed);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public boolean tryAcquire() {
        // 漏桶里面放水
        return bucket.offer(this);
    }

    public static void main(String[] args) throws InterruptedException {
        Funnel funnel = new Funnel(10, 100);
        while ( true) {
            if (funnel.tryAcquire()) {
                System.out.println("请求成功...");
            } else {
                System.out.println("限流了...");
            }
            Thread.sleep(20 * new Random().nextInt(5));
        }
    }
}
